package com.boarsoft.gateway.handler;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.boarsoft.common.Util;
import com.boarsoft.soagov.route.ServiceRouter;
import com.boarsoft.webapp.HttpServiceHandler;
import com.boarsoft.webapp.mock.HttpMocker;

/**
 * 暂时维持现状
 * 
 * @author Mac_J
 *
 */
public class DefaultHttpHandlerImpl implements HttpServiceHandler {
	private final Logger log = LoggerFactory.getLogger(this.getClass());

	/** key: 服务编号-版本号, value: 服务节点地址 */
	protected Map<String, ServiceRouter<HttpServletRequest>> routerMap = new HashMap<>();
	/** */
	protected Map<String, HttpMocker> mockerMap = new ConcurrentHashMap<String, HttpMocker>();

	@Override
	public boolean process(final HttpServletRequest req, final HttpServletResponse rsp)
			throws ServletException, IOException {
		// 从请求头中提取上下文、服务消费者（客户端）版本号、测试用户白名单
		String cp = req.getPathInfo();
		if (cp.length() < 1) {
			rsp.sendError(HttpStatus.BAD_REQUEST_400);
			return true;
		}
		cp = cp.substring(1);
		int i = cp.indexOf("/");
		if (i < 1) {
			rsp.sendError(HttpStatus.BAD_REQUEST_400);
			return true;
		}
		String sc = cp.substring(0, i);
		// 获取要路由的目标地址
		ServiceRouter<HttpServletRequest> sr = routerMap.get(sc);
		// 判断是否启用挡板
		if (sr == null) {
			if (mockerMap.containsKey(sc)) {
				HttpMocker mocker = mockerMap.get(sc);
				if (mocker.mock(req, rsp)) {
					return true;
				}
			}
			rsp.sendError(HttpStatus.NOT_ACCEPTABLE_406);
			return true;
		}
		req.setAttribute("app", sc);
		String sa = sr.getProvider(req);
		if (Util.strIsNotEmpty(sa)) {
			// 替换原请求中的域名为实际提供服务的应用地址
			StringBuffer sb = new StringBuffer().append(req.getRequestURL());
			// http://xxx/.... 替换xxx部份
			i = sb.substring(7).indexOf("/") + 7;
			sb.replace(7, i, sa);
			String qs = req.getQueryString();
			if (!StringUtils.isEmpty(qs)) {
				sb.append("?").append(qs);
			}
			String url = sb.toString();
			log.debug("rewrite {} to {}", req.getRequestURI(), url);
			req.setAttribute("rewriteUrl", url);
		}
		// 如果有配挡板，调用挡板
		if (mockerMap.containsKey(sc)) {
			HttpMocker mocker = mockerMap.get(sc);
			if (mocker.mock(req, rsp)) {
				return true;
			}
		}
		return false;
	}

	protected String getCookieValue(HttpServletRequest req, String name) {
		Cookie[] cookies = req.getCookies();
		if (cookies == null) {
			return null;
		}
		for (Cookie c : cookies) {
			if (name.equals(c.getName())) {
				return c.getValue();
			}
		}
		return null;
	}

	public Map<String, ServiceRouter<HttpServletRequest>> getRouterMap() {
		return routerMap;
	}

	public void setRouterMap(Map<String, ServiceRouter<HttpServletRequest>> routerMap) {
		this.routerMap = routerMap;
	}

	public Map<String, HttpMocker> getMockerMap() {
		return mockerMap;
	}

	public void setMockerMap(Map<String, HttpMocker> mockerMap) {
		this.mockerMap = mockerMap;
	}
}